// wait_group 实现有条件的等待
#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/Workflow.h>
#include <iostream>
#include <signal.h>
using std::cout;
using std::cerr;
using std::vector;
using std::string;
struct SeriesContext{
    string url;
    size_t body_len;
};
static WFFacilities::WaitGroup waitGroup(1);
void handler(int signum){
    cout << "done\n";
    waitGroup.done();
}

void httpCallback(WFHttpTask *httpTask){
	protocol::HttpResponse *resp = httpTask->get_resp(); // 获取响应
	int state = httpTask->get_state(); // 获取状态
	int error = httpTask->get_error(); // 获取错误原因
	switch (state){
	case WFT_STATE_SYS_ERROR:
		cerr <<"system error: " << strerror(error) << "\n";
		break;
	case WFT_STATE_DNS_ERROR:
		cerr <<"DNS error: "  << gai_strerror(error) << "\n";
		break;
	case WFT_STATE_SSL_ERROR:
		cerr <<"SSL error\n";
		break;
	case WFT_STATE_TASK_ERROR:
		cerr <<"Task error\n";
		break;
	case WFT_STATE_SUCCESS:
		break;
	}
	if (state != WFT_STATE_SUCCESS){
		cerr <<"Failed. Press Ctrl-C to exit.\n";
		return;
	}

	const void *body;
	size_t body_len;
	resp->get_parsed_body(&body, &body_len); // get_parsed_body找到响应报文的报文体
    SeriesContext * context = static_cast<SeriesContext *>(series_of(httpTask)->get_context());
    context->body_len = body_len;
    cerr << "url = " << context->url << ", len = " << context->body_len << "\n";
}
void parallelCallback(const ParallelWork * parallelWork){
    cerr << "parallel callback\n";
    string name;
    size_t body_len = 0;
    for(int i = 0; i < 3; ++i){
        // 找到内部的（已经执行完成不可修改的）序列
        const SeriesWork * series = parallelWork->series_at(i);
        SeriesContext * context = static_cast<SeriesContext *>(series->get_context());
        cerr << "i = " << i << "url = " << context->url << ", len = " << context->body_len << "\n";
        if(body_len < context->body_len){
            body_len = context->body_len;
            name = context->url;
        }
        delete context;
    }
    cerr << "longest body_len  url = " << name << " body_len = " << body_len <<"\n";

    WFRedisTask * redisTask = WFTaskFactory::create_redis_task(
        "redis://127.0.0.1:6379",10,nullptr
    );
    redisTask->get_req()->set_request("SET",{name,std::to_string(body_len)});
    series_of(parallelWork)->push_back(redisTask);
}
int main(){
    signal(SIGINT,handler);
    // 创建一个空的并行任务
    ParallelWork * parallelWork = Workflow::create_parallel_work(parallelCallback);
    // 创建多个小序列
    vector<string> urls = {
        "http://www.taobao.com",
        "http://www.jd.com",
        "http://www.baidu.com"
    };
    for(int i = 0; i < 3; ++i){
        // 创建一个http任务
        WFHttpTask * httpTask = WFTaskFactory::create_http_task(urls[i],10,10,httpCallback);
        // 根据http任务创建小序列
        SeriesWork * series =  Workflow::create_series_work(httpTask,nullptr);
        // 往序列中加一个context
        SeriesContext *context = new SeriesContext;
        context->url = urls[i];
        series->set_context(context);
        // 把小序列加入并行任务
        parallelWork->add_series(series);
    }

    parallelWork->start();
    waitGroup.wait();
    cout << "finish!\n";
}
